package com.kxmall.web.controller.address;

import com.kxmall.address.domain.bo.KxAddressBo;
import com.kxmall.address.domain.vo.KxAddressVo;
import com.kxmall.common.annotation.RepeatSubmit;
import com.kxmall.common.core.controller.BaseAppController;
import com.kxmall.common.core.domain.PageQuery;
import com.kxmall.common.core.domain.R;
import com.kxmall.common.core.page.TableDataInfo;
import com.kxmall.common.core.validate.AddGroup;
import com.kxmall.common.core.validate.EditGroup;
import com.kxmall.web.controller.address.service.IKxAddressService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

/**
 * 用户下单地址
 *
 * @author kxmall
 * @date 2023-04-06
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/address/app")
public class KxAddressController extends BaseAppController {

    /**
     * 高德地图API密钥
     */
    @Value("${kxmall.amap.api-key:your_amap_api_key}")
    private String amapApiKey;

    private final IKxAddressService iKxAddressService;

    /**
     * 查询用户下单地址列表
     */
    @GetMapping("/list")
    public TableDataInfo<KxAddressVo> list(KxAddressBo bo, PageQuery pageQuery) {
        return iKxAddressService.queryPageList(bo, pageQuery);
    }


    /**
     * 查询用户下单地址列表
     */
    @GetMapping("/getAllAddress")
    public R<List<KxAddressVo>> getAllAddress() {
        KxAddressBo bo = new KxAddressBo();
        bo.setUserId(getAppLoginUser().getUserId());
        return R.ok(iKxAddressService.queryList(bo));
    }

    /**
     * 获取用户下单地址详细信息
     *
     * @param id 主键
     */
    @GetMapping("/{id}")
    public R<KxAddressVo> getInfo(@NotNull(message = "主键不能为空")
                                  @PathVariable Long id) {
        return R.ok(iKxAddressService.queryById(id));
    }


    /**
     * 获取默认地址
     */
    @GetMapping("/getDefAddress")
    public R<KxAddressVo> getDefAddress() {
        Long userId = getAppLoginUser().getUserId();
        return R.ok(iKxAddressService.getDefAddress(userId));
    }

    /**
     * 新增用户下单地址
     */
    @RepeatSubmit()
    @PostMapping("/addAddress")
    public R<Void> add(@Validated(AddGroup.class) @RequestBody KxAddressBo bo) {
        bo.setUserId(getAppLoginUser().getUserId());

        // 如果经纬度为空，尝试通过高德地图API解析获取
        if (bo.getLongitude() == null || bo.getLatitude() == null) {
            log.info("📍 新增地址经纬度为空，开始地址解析。省份：{}，城市：{}，区县：{}，详细地址：{}",
                    bo.getProvince(), bo.getCity(), bo.getCounty(), bo.getAddress());

            try {
                BigDecimal[] coordinates = getCoordinatesByAmap(bo.getProvince(), bo.getCity(), bo.getCounty(), bo.getAddress());
                if (coordinates != null && coordinates.length == 2) {
                    bo.setLongitude(coordinates[0]);
                    bo.setLatitude(coordinates[1]);
                    log.info("✅ 新增地址-高德地图API解析成功！经度：{}，纬度：{}", coordinates[0], coordinates[1]);
                } else {
                    // 解析失败时使用默认坐标，确保能正常录入
                    log.warn("❌ 新增地址-高德地图API解析失败，使用默认坐标");
                    setDefaultCoordinates(bo);
                }
            } catch (Exception e) {
                log.error("新增地址-地址解析异常", e);
                // 异常时也使用默认坐标，确保能正常录入
                log.warn("⚠️ 新增地址-地址解析异常，使用默认坐标");
                setDefaultCoordinates(bo);
            }
        }

        return toAjax(iKxAddressService.insertByBo(bo));
    }

    /**
     * 修改用户下单地址
     */
    @RepeatSubmit()
    @PostMapping("/updateAddress")
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody KxAddressBo bo) {
        bo.setUserId(getAppLoginUser().getUserId());

        // 如果经纬度为空，尝试通过高德地图API解析获取
        if (bo.getLongitude() == null || bo.getLatitude() == null) {
            log.info("📍 修改地址经纬度为空，开始地址解析。省份：{}，城市：{}，区县：{}，详细地址：{}",
                    bo.getProvince(), bo.getCity(), bo.getCounty(), bo.getAddress());

            try {
                BigDecimal[] coordinates = getCoordinatesByAmap(bo.getProvince(), bo.getCity(), bo.getCounty(), bo.getAddress());
                if (coordinates != null && coordinates.length == 2) {
                    bo.setLongitude(coordinates[0]);
                    bo.setLatitude(coordinates[1]);
                    log.info("✅ 修改地址-高德地图API解析成功！经度：{}，纬度：{}", coordinates[0], coordinates[1]);
                } else {
                    // 解析失败时使用默认坐标，确保能正常录入
                    log.warn("❌ 修改地址-高德地图API解析失败，使用默认坐标");
                    setDefaultCoordinates(bo);
                }
            } catch (Exception e) {
                log.error("修改地址-地址解析异常", e);
                // 异常时也使用默认坐标，确保能正常录入
                log.warn("⚠️ 修改地址-地址解析异常，使用默认坐标");
                setDefaultCoordinates(bo);
            }
        }

        return toAjax(iKxAddressService.updateByBo(bo));
    }

    /**
     * 删除地址
     */
    @RepeatSubmit()
    @PostMapping("/deleteAddress")
    public R<Void> deleteAddress(@Validated(EditGroup.class) @RequestBody KxAddressBo bo) {
        bo.setUserId(getAppLoginUser().getUserId());
        return toAjax(iKxAddressService.deleteAddress(bo));
    }

    /**
     * 删除用户下单地址
     *
     * @param ids 主键串
     */
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(iKxAddressService.deleteWithValidByIds(Arrays.asList(ids), true));
    }

    /**
     * 通过高德地图API获取经纬度坐标
     *
     * @param province 省份
     * @param city 城市
     * @param county 区县
     * @param address 详细地址
     * @return 经纬度数组 [经度, 纬度]，失败返回null
     */
    private BigDecimal[] getCoordinatesByAmap(String province, String city, String county, String address) {
        try {
            // 检查API密钥是否配置
            if ("your_amap_api_key".equals(amapApiKey) || amapApiKey == null || amapApiKey.trim().isEmpty()) {
                log.warn("❌ 高德地图API密钥未配置或无效，请在配置文件中设置 kxmall.amap.api-key");
                return null;
            }

            // 构建完整地址
            StringBuilder fullAddress = new StringBuilder();
            if (province != null && !province.trim().isEmpty()) {
                fullAddress.append(province.trim());
            }
            if (city != null && !city.trim().isEmpty()) {
                fullAddress.append(city.trim());
            }
            if (county != null && !county.trim().isEmpty()) {
                fullAddress.append(county.trim());
            }
            if (address != null && !address.trim().isEmpty()) {
                fullAddress.append(address.trim());
            }

            String addressStr = fullAddress.toString();
            if (addressStr.isEmpty()) {
                return null;
            }

            // 构建高德地图地理编码API请求URL
            String encodedAddress = java.net.URLEncoder.encode(addressStr, "UTF-8");
            String apiUrl = String.format("https://restapi.amap.com/v3/geocode/geo?key=%s&address=%s",
                    amapApiKey, encodedAddress);

            // 发送HTTP请求
            String response = sendHttpRequest(apiUrl);
            if (response == null || response.trim().isEmpty()) {
                log.warn("高德地图API返回空响应");
                return null;
            }

            // 解析响应结果
            com.alibaba.fastjson.JSONObject jsonResponse = com.alibaba.fastjson.JSON.parseObject(response);
            String status = jsonResponse.getString("status");

            if (!"1".equals(status)) {
                log.warn("高德地图API返回错误，状态：{}，信息：{}", status, jsonResponse.getString("info"));
                return null;
            }

            com.alibaba.fastjson.JSONArray geocodes = jsonResponse.getJSONArray("geocodes");
            if (geocodes == null || geocodes.isEmpty()) {
                log.warn("高德地图API未找到匹配的地址：{}", addressStr);
                return null;
            }

            com.alibaba.fastjson.JSONObject geocode = geocodes.getJSONObject(0);
            String location = geocode.getString("location");
            if (location == null || location.trim().isEmpty()) {
                log.warn("高德地图API返回的坐标为空");
                return null;
            }

            String[] coords = location.split(",");
            if (coords.length != 2) {
                log.warn("高德地图API返回的坐标格式错误：{}", location);
                return null;
            }

            BigDecimal longitude = new BigDecimal(coords[0]);
            BigDecimal latitude = new BigDecimal(coords[1]);

            log.info("🎯 地址解析成功！输入：{}，结果：经度：{}，纬度：{}", addressStr, longitude, latitude);
            return new BigDecimal[]{longitude, latitude};

        } catch (Exception e) {
            log.error("高德地图地理编码异常", e);
            return null;
        }
    }

    /**
     * 发送HTTP请求
     */
    private String sendHttpRequest(String urlStr) {
        try {
            java.net.URL url = new java.net.URL(urlStr);
            java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(10000);
            connection.setRequestProperty("User-Agent", "Mozilla/5.0");

            int responseCode = connection.getResponseCode();
            if (responseCode != java.net.HttpURLConnection.HTTP_OK) {
                log.error("HTTP请求失败，响应码：{}", responseCode);
                return null;
            }

            java.io.BufferedReader reader = new java.io.BufferedReader(
                    new java.io.InputStreamReader(connection.getInputStream(), "UTF-8"));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            connection.disconnect();

            return response.toString();

        } catch (Exception e) {
            log.error("HTTP请求异常", e);
            return null;
        }
    }

    /**
     * 设置默认坐标
     */
    private void setDefaultCoordinates(KxAddressBo bo) {
        String city = bo.getCity();
        if (city == null) {
            city = "";
        }

        // 根据城市设置默认坐标
        if (city.contains("乌海")) {
            bo.setLongitude(new BigDecimal("106.794249"));
            bo.setLatitude(new BigDecimal("39.655388"));
            log.info("🏠 使用乌海市默认坐标：经度：106.794249，纬度：39.655388");
        } else if (city.contains("北京")) {
            bo.setLongitude(new BigDecimal("116.404"));
            bo.setLatitude(new BigDecimal("39.915"));
            log.info("🏠 使用北京默认坐标：经度：116.404，纬度：39.915");
        } else if (city.contains("上海")) {
            bo.setLongitude(new BigDecimal("121.473"));
            bo.setLatitude(new BigDecimal("31.230"));
            log.info("🏠 使用上海默认坐标：经度：121.473，纬度：31.230");
        } else if (city.contains("广州")) {
            bo.setLongitude(new BigDecimal("113.264"));
            bo.setLatitude(new BigDecimal("23.129"));
            log.info("🏠 使用广州默认坐标：经度：113.264，纬度：23.129");
        } else if (city.contains("深圳")) {
            bo.setLongitude(new BigDecimal("114.057"));
            bo.setLatitude(new BigDecimal("22.543"));
            log.info("🏠 使用深圳默认坐标：经度：114.057，纬度：22.543");
        } else {
            // 默认使用北京坐标
            bo.setLongitude(new BigDecimal("116.404"));
            bo.setLatitude(new BigDecimal("39.915"));
            log.info("🏠 使用默认坐标（北京）：经度：116.404，纬度：39.915");
        }
    }
}
